﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;

namespace MvcOSGi.Shell.Infra
{
    public static class EnumExtensions
    {
        public static bool Any<T>(this T value, params Enum[] values)
        {
            if (value != null && values != null)
            {
                var valueType = value.GetType();
                foreach (var enumValue in values)
                {
                    var enumType = enumValue.GetType();
                    if (valueType.Equals(enumType))
                    {
                        if (value.Equals(enumValue)) return true;
                    }
                    else
                    {
                        if (Enum.GetUnderlyingType(enumType).Equals(valueType)
                            && Enum.IsDefined(enumType, value)
                            && Enum.ToObject(enumType, value).Equals(enumValue)) return true;
                    }
                }
            }
            return false;
        }

        public static string GetDescription<TEnum>(this TEnum value) where TEnum : struct, IConvertible
        {
            if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
            var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
            return attributes != null && attributes.Length > 0 ? attributes[0].Description : value.ToString();
        }

        public static IEnumerable<TEnum> GetValues<TEnum>() where TEnum : struct, IConvertible
        {
            return Enum.GetValues(typeof(TEnum)).Cast<TEnum>();
        }

        public static T GetValueFromDescription<T>(string description)
        {
            var type = typeof(T);
            if (!type.IsEnum) throw new InvalidOperationException();
            foreach (var field in type.GetFields())
            {
                var attribute = Attribute.GetCustomAttribute(field,
                    typeof(DescriptionAttribute)) as DescriptionAttribute;
                if (attribute != null)
                {
                    if (attribute.Description.Equals(description, StringComparison.CurrentCultureIgnoreCase))
                        return (T)field.GetValue(null);
                }
                else
                {
                    if (field.Name.Equals(description, StringComparison.CurrentCultureIgnoreCase))
                        return (T)field.GetValue(null);
                }
            }
            return default(T);
        }
    }
}